#include "SimpleShader.h"
#include "IObject.h"

SimpleShader::SimpleShader(void)
{	
}

SimpleShader::~SimpleShader(void)
{
	g_pCBChangesOnResize->Release();
	g_pCBChangesEveryFrame->Release();
}


HRESULT SimpleShader::Init(const char* effectName,const char* VsName, const char* vsVersion, const char* PsName,const char* psVersion, VertexLayout vl, const char* GsName ,const char* GsVersion , D3D11_SO_DECLARATION_ENTRY declaration[] , int nElements ,UINT* stride , UINT numStrides)
{
	HRESULT hr = S_OK;
	hr = IShader::Init(effectName,VsName,vsVersion,PsName,psVersion,vl);
	CheckError(hr);

	// Create the constant buffers
	D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;                    
    bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
    bd.CPUAccessFlags = 0;    
    bd.ByteWidth = sizeof(CBChangesEveryFrame);	
	hr = EngineStuff::EGraphicsDevice->CreateBuffer( &bd, NULL, &g_pCBChangesEveryFrame);
    CheckError(hr);

	bd.ByteWidth = sizeof(CBChangeOnResize);
	hr = EngineStuff::EGraphicsDevice->CreateBuffer( &bd, NULL, &g_pCBChangesOnResize);
    CheckError(hr);
	
    // Create the sample state
    D3D11_SAMPLER_DESC sampDesc;
    ZeroMemory( &sampDesc, sizeof(sampDesc) );
    sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
    sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
    sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
    sampDesc.MinLOD = 0;
    sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
	hr = EngineStuff::EGraphicsDevice->CreateSamplerState( &sampDesc, &g_pSamplerLinear );
    CheckError(hr);

	return hr;
}

void SimpleShader::SetShaderOnDevice(RenderableObject obj)
{		
	IShader::SetShaderOnDevice(obj);

    EngineStuff::EImediateDeviceContext->UpdateSubresource( g_pCBChangesEveryFrame, 0, NULL, &cbChangesEveryFrame, 0, 0 );
	EngineStuff::EImediateDeviceContext->UpdateSubresource( g_pCBChangesOnResize, 0, NULL, &cbChangeOnResize, 0, 0 );
	
    EngineStuff::EImediateDeviceContext->VSSetConstantBuffers( 0, 1, &g_pCBChangesEveryFrame );
	EngineStuff::EImediateDeviceContext->VSSetConstantBuffers( 1, 1, &g_pCBChangesOnResize );    

	ID3D11ShaderResourceView* texture = obj.IOBJECT->GetMesh()->GetTexture(TextureTypes::Diffuse);
	EngineStuff::EImediateDeviceContext->PSSetShaderResources(0, 1, &texture );
    EngineStuff::EImediateDeviceContext->PSSetSamplers( 0, 1, &g_pSamplerLinear );

}

void SimpleShader::Update(RenderableObject obj,Camera* camera)
{		
		XMStoreFloat4x4(&cbChangeOnResize.Projection ,XMMatrixTranspose( camera->getProjectionMatrix() ));
		XMStoreFloat4x4(&cbChangesEveryFrame.View,XMMatrixTranspose(camera->getViewMatrix()));		
		XMStoreFloat4x4(&cbChangesEveryFrame.World, XMMatrixTranspose(*obj.IOBJECT->GetMesh()->Transformation  * *obj.IOBJECT->GetPhysicObject()->GetWorldTransformation() ));		
		
}
